package com.qingyun.quartz.task;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.http.HttpUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.qingyun.common.config.QingYunConfig;
import com.qingyun.common.constant.Constants;
import com.qingyun.quartz.domain.TiktokPushTask;
import com.qingyun.quartz.service.ITiktokPushTaskService;
import com.qingyun.shop.domain.*;
import com.qingyun.shop.domain.vo.TiktokActivityVo;
import com.qingyun.shop.mapper.TiktokTagToVoiceMapper;
import com.qingyun.shop.service.*;
import com.qingyun.tiktok.basis.body.interaction.ItemCommentReplyReqBody;
import com.qingyun.tiktok.basis.body.video.AutoCreateVideoParam;
import com.qingyun.tiktok.basis.response.video.VideoCreateRes;
import com.qingyun.tiktok.basis.service.interfaces.DyBasisService;
import com.qingyun.tiktok.common.bean.AccessToken;
import com.qingyun.tiktok.common.enums.ApiPlatform;
import com.qingyun.tiktok.common.enums.ErrorCode;
import com.qingyun.tiktok.domain.TiktokVideoSend;
import com.qingyun.tiktok.domain.vo.TiktokUserVo;
import com.qingyun.tiktok.service.ITiktokUserService;
import com.qingyun.tiktok.service.ITiktokVideoSendService;
import com.qingyun.video.config.FFmpegConfig;
import com.qingyun.video.domain.TiktokVideoMerge;
import com.qingyun.shop.service.ITiktokBgmService;
import com.qingyun.video.ffmpeg.Encoder;
import com.qingyun.video.service.ITiktokVideoMergeService;
import com.qingyun.video.utils.VideoUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;

/**
 * @Classname VideoSendService
 * @Author dyh
 * @Date 2021/9/15 18:07
 */
@Service
@EnableAsync
@AllArgsConstructor
@Slf4j
public class VideoSendService {

	private ITiktokVideoMergeService videoMergeService;

	private ITiktokVideoSendService videoSendService;

	private ITiktokResourceService resourceService;

	private ITiktokResourceGroupService resourceGroupService;

	private ITiktokActivityService activityService;

	private ITiktokShopService shopService;

	private ITiktokUserService userService;

	private ITiktokBgmService bgmService;

	private ITiktokPushTaskService pushTaskService;

	private ITiktokShopInfoService tiktokShopInfoService;

	private DyBasisService dyBasisService;

	private TiktokTagToVoiceMapper tagToVoiceMapper;

	private ITiktokShopDocumentService shopDocumentService;

	@Async
	public void asyncMergeVideoSend(Long activityId, Long userId, Long taskId) throws FileNotFoundException {
		this.mergeVideoSend(activityId, userId, taskId);
	}

	public Boolean mergeVideoSend(Long activityId, Long userId, Long taskId) throws FileNotFoundException {

		TiktokActivityVo tiktokActivityVo = activityService.getVoById(activityId);
		TiktokShop shop = shopService.getById(tiktokActivityVo.getShopId());
		TiktokUserVo user = userService.queryById(userId);
		//如果是单视频固定文件
		if (tiktokActivityVo.getVideoSource().equals(1)) {
			String localPath = QingYunConfig.getProfile() + StringUtils.substringAfter(tiktokActivityVo.getVideoUrl(), Constants.RESOURCE_PREFIX);
			sendVideo(localPath, tiktokActivityVo, user, taskId);
			return true;
		}
		//如果是随机获取视频文件
		List<String> paths = new ArrayList<>();
		List<TiktokResource> tiktokResources = new ArrayList<>();
		TiktokBgm bgm ;
		String ids ;
		Map<String,String> voice=null;
		//是否碎片化混剪 1否
		if (tiktokActivityVo.getIsRandFrag().equals(1)) {
			//随机获取一个资源
			TiktokResource tiktokResource = resourceService.selectRandomResourceByGroupId(shop.getId(), null, null, 1);
			if(ObjectUtil.isNull(tiktokResource)){
				//不存在就不发送
				return false;
			}
			Integer resourceType = tiktokResource.getResourceType();
			String resourceUrl = tiktokResource.getResourceUrl();
			String localPath = QingYunConfig.getProfile() + StringUtils.substringAfter(resourceUrl, Constants.RESOURCE_PREFIX);
			if (resourceType.equals(2)) {
				//如果是音频直接发送
				sendVideo(localPath, tiktokActivityVo, user, taskId);
				return true;
			} else {
				ids = String.valueOf(tiktokResource.getId());
				tiktokResources.add(tiktokResource);
				//如果是视频 添加bgm混剪
				paths.add(localPath);
				bgm = bgmService.selectBgmBy(shop.getId(), activityId, tiktokResource.getDuration(),true);
				if (ObjectUtil.isNull(bgm)) {
					//不存在时间大于视频的bgm就随机抽一个
					bgm = bgmService.selectBgmBy(shop.getId(), activityId, null,false);
					if(ObjectUtil.isNull(bgm)){
						bgm = bgmService.lambdaQuery().eq(TiktokBgm::getShopId,shop.getId()).or().eq(TiktokBgm::getGlobal,0).last("order by rand() limit 1").one();
					}
				}
			}
		} else {
			//分组碎片随机获取
			Double totalDuration = 0D;
			tiktokResources = mergeVideo(shop.getId());
			StringBuilder builder = new StringBuilder();
			for (TiktokResource tiktokResource : tiktokResources) {
				String localPath = QingYunConfig.getProfile() + StringUtils.substringAfter(tiktokResource.getResourceUrl(), Constants.RESOURCE_PREFIX);
				builder.append(tiktokResource.getId()).append(",");
				paths.add(localPath);
				totalDuration = totalDuration + tiktokResource.getDuration();
			}
			ids = builder.toString();
			log.warn("混剪视频id列表"+ids);
			if(StringUtils.isBlank(ids)){
				return false;
			}
			ids = ids.substring(0, ids.lastIndexOf(","));
			// 根据活动标签随机获取最匹配的bgm
			bgm = bgmService.selectBgmBy(shop.getId(), activityId, totalDuration,true);
			if (ObjectUtil.isNull(bgm)) {
				//不存在时间大于视频的bgm就随机抽一个（会导致视频时间跟随音乐时间长短
				bgm = bgmService.selectBgmBy(shop.getId(), activityId, totalDuration,false);
				if(ObjectUtil.isNull(bgm)){
					bgm = bgmService.lambdaQuery().eq(TiktokBgm::getShopId,shop.getId()).or().eq(TiktokBgm::getGlobal,0).last("order by rand() limit 1").one();
				}
			}
			log.warn("bgm名称 "+bgm.getTitle());
			if(ObjectUtil.isNull(bgm)){
				return false;
			}
			//如果活动对应了语音的标签就使用语音 音乐则为背景音乐
			voice=tagToVoiceMapper.selectRandTagVoice(activityId);

			//todo 资源音乐让用户选择是否存在音乐 存在就不混剪 不存在还是走混剪路线
		}

		String audioUrl = QingYunConfig.getProfile() + StringUtils.substringAfter(bgm.getAudioUrl(), Constants.RESOURCE_PREFIX);
		TiktokVideoMerge tiktokVideoMerge = new TiktokVideoMerge();
		tiktokVideoMerge.setResourceBgm(String.valueOf(bgm.getId()));
		tiktokVideoMerge.setShopId(shop.getId());
		tiktokVideoMerge.setResourceIds(ids);
		tiktokVideoMerge.setTaskId(taskId);
		tiktokVideoMerge.setCreateTime(new Date());
		//这里剪辑到本地
		String mergePath = FFmpegConfig.getTempAbsolutePath() + VideoUtil.nowTime() + ".mp4";
		if (CollectionUtil.isEmpty(paths)) {
			return false;
		}
		boolean mergeStatus=false;
		if (ObjectUtil.isNull(voice)) {
			mergeStatus= VideoUtil.mergeVideo(mergePath, paths, true, audioUrl,null,null);
		}else {
			String voicePath = QingYunConfig.getProfile() + StringUtils.substringAfter(voice.get("voice"), Constants.RESOURCE_PREFIX);
			String srtPath = QingYunConfig.getProfile() + StringUtils.substringAfter(voice.get("srt"), Constants.RESOURCE_PREFIX);
			mergeStatus= VideoUtil.mergeVideo(mergePath, paths, true,voicePath,audioUrl,srtPath);
		}
		if (mergeStatus) {
			//合成成功
			tiktokVideoMerge.setStatus(0);
			tiktokVideoMerge.setResourceUrl(mergePath);
			videoMergeService.save(tiktokVideoMerge);
			//发送视频
			sendVideo(mergePath, tiktokActivityVo, user, taskId);
		} else {//混剪失败记录
			TiktokVideoSend tiktokVideoSend = new TiktokVideoSend();
			tiktokVideoSend.setActivityId(activityId);
			if (taskId != null) {
				tiktokVideoSend.setTaskId(taskId);
				TiktokPushTask pushTask = pushTaskService.getById(taskId);
				pushTask.setStatus(2);
				pushTaskService.updateById(pushTask);
			} else {
				tiktokVideoSend.setTaskId(0L);
			}
			tiktokVideoSend.setTiktokUserId(user.getId());
			tiktokVideoSend.setTiktokNickName(user.getNickName());
			tiktokVideoSend.setOpenId(user.getOpenId());
			tiktokVideoSend.setStatus(2);
			tiktokVideoSend.setCreateTime(new Date());
			videoSendService.save(tiktokVideoSend);
			tiktokVideoMerge.setStatus(1);
			//合成失败
			videoMergeService.save(tiktokVideoMerge);
			return Boolean.FALSE;
		}
		return Boolean.TRUE;
	}


	/**
	 * 发送视频
	 *
	 * @param mergePath
	 * @param tiktokActivityVo
	 * @param user
	 * @param taskId
	 * @return
	 * @throws FileNotFoundException
	 */
	public Boolean sendVideo(String mergePath, TiktokActivityVo tiktokActivityVo, TiktokUserVo user, Long taskId) throws FileNotFoundException {

		AutoCreateVideoParam autoCreateVideoParam = new AutoCreateVideoParam();
		//查询活动关联的商户抖音信息

		TiktokShopInfo tiktokshopinfo = tiktokShopInfoService.lambdaQuery().eq(TiktokShopInfo::getShopId, tiktokActivityVo.getShopId()).one();

		//如果标题为空就走文案库里随机抽取
		TiktokShopDocument one=null;
		if(tiktokActivityVo.getIsDoc().equals(1)) {
			 one = shopDocumentService.lambdaQuery()
				.eq(TiktokShopDocument::getShopId, tiktokActivityVo.getShopId())
				.last("order by rand() limit 1").one();
			tiktokActivityVo.setVideoTitle(one.getContext());
		}
		//添加话题
		autoCreateVideoParam = setText(autoCreateVideoParam, tiktokActivityVo, tiktokshopinfo);
		//添加位置
		if (StringUtils.isNoneBlank(tiktokActivityVo.getPoiId(),tiktokActivityVo.getPoiName())) {
			autoCreateVideoParam.setPoiId(tiktokActivityVo.getPoiId());
			autoCreateVideoParam.setPoiName(tiktokActivityVo.getPoiName());
		}else{
			if (StringUtils.isNoneBlank(tiktokshopinfo.getPoiId(),tiktokshopinfo.getPoiName())) {
				autoCreateVideoParam.setPoiId(tiktokshopinfo.getPoiId());
				autoCreateVideoParam.setPoiName(tiktokshopinfo.getPoiName());
			}
		}

		//添加小程序
		if (StringUtils.isNoneBlank(tiktokActivityVo.getMiniAppId(),tiktokActivityVo.getMiniAppTitle())) {
			autoCreateVideoParam.setMicroAppId(tiktokActivityVo.getMiniAppId());
			autoCreateVideoParam.setMicroAppTitle(tiktokActivityVo.getMiniAppTitle());
		}else{
			if(StringUtils.isNoneBlank(tiktokshopinfo.getMiniAppId(),tiktokshopinfo.getMiniAppTitle())) {
				autoCreateVideoParam.setMicroAppId(tiktokshopinfo.getMiniAppId());
				autoCreateVideoParam.setMicroAppTitle(tiktokshopinfo.getMiniAppTitle());
			}
		}
		log.info("开始发送视频");
		//发送视频
		VideoCreateRes.VideoCreateResData videoCreateResData =
			dyBasisService.getVideoService().autoCreateVideo(user.getOpenId(), new File(mergePath), autoCreateVideoParam, ApiPlatform.DOU_YIN);

		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		log.info("开始添加评论");
		//添加评论
		if(ObjectUtil.isNotNull(one)){
			if (StringUtils.isNotBlank(one.getCommon())) {
				String[] split = one.getCommon().split(",");
				log.warn("添加评论");
				for (String comment : split) {
					ItemCommentReplyReqBody itemCommentReplyReqBody=new ItemCommentReplyReqBody();
					itemCommentReplyReqBody.setContent(comment);
					itemCommentReplyReqBody.setItemId(videoCreateResData.getItemId());
					dyBasisService.getInteractionManagerService().sendComment(user.getOpenId(),itemCommentReplyReqBody,ApiPlatform.DOU_YIN);
				}
			}

		}


		//发送记录
		TiktokVideoSend tiktokVideoSend = new TiktokVideoSend();
		tiktokVideoSend.setCreateTime(new Date());
		tiktokVideoSend.setOpenId(user.getOpenId());
		tiktokVideoSend.setTiktokUserId(user.getId());
		tiktokVideoSend.setTiktokNickName(user.getNickName());
		tiktokVideoSend.setTaskId(taskId);
		tiktokVideoSend.setActivityId(tiktokActivityVo.getId());
		tiktokVideoSend.setShopId(tiktokActivityVo.getShopId());
		tiktokVideoSend.setVideoPath(mergePath);
		if (videoCreateResData.getErrorCode() == ErrorCode.SUCCESS.getValue()) {
			if (taskId != null) {
				TiktokPushTask task = pushTaskService.getById(taskId);
				task.setStatus(1);
				pushTaskService.updateById(task);
			}
			tiktokVideoSend.setItemId(videoCreateResData.getItemId());
			tiktokVideoSend.setStatus(1);
			videoSendService.save(tiktokVideoSend);
			return true;
		} else {
			if (taskId != null) {
				TiktokPushTask task = pushTaskService.getById(taskId);
				task.setStatus(2);
				pushTaskService.updateById(task);
			}
			tiktokVideoSend.setStatus(2);
			videoSendService.save(tiktokVideoSend);
			return false;
		}
	}

	/**
	 * 组合视频列表
	 *
	 * @return
	 */
	public List<TiktokResource> mergeVideo(Long shopId) {
		List<TiktokResourceGroup> list = resourceGroupService.lambdaQuery().eq(TiktokResourceGroup::getShopId, shopId).last("limit 5").list();
		List<TiktokResource> resources = new ArrayList<>();
		TiktokResource tiktokResource = null;
		Integer format = 0;
		for (int i = 0; i < list.size(); i++) {
			if (i == 0) {
				tiktokResource = resourceService.selectRandomResourceByGroupId(shopId, list.get(i).getId(), null, 0);
				if(tiktokResource!=null){
					format = tiktokResource.getFormat();
				}
				//如果第一条不是碎片视频就进行下一条也不是碎片视频 并且他们分辨率要一致
			} else {
				tiktokResource = resourceService.selectRandomResourceByGroupId(shopId, list.get(i).getId(), format, 0);
				if(tiktokResource!=null){
					format = tiktokResource.getFormat();
				}
			}
			if (ObjectUtil.isNotNull(tiktokResource)) {
				resources.add(tiktokResource);
			}
		}

		return resources;
	}

	public static void main(String[] args) {
		System.out.println();
	}

	/**
	 * 添加话题
	 *
	 * @param autoCreateVideoParam
	 * @param activity
	 * @return
	 */
	private AutoCreateVideoParam setText(AutoCreateVideoParam autoCreateVideoParam, TiktokActivityVo activity, TiktokShopInfo shopInfo) {
		String text = activity.getVideoTitle();

		//话题
		if (StringUtils.isNotEmpty(activity.getDouyinTitle())) {
			text = text + activity.getDouyinTitle();
		}
		//@商家
		if (StringUtils.isNotEmpty(shopInfo.getOpenId())) {
			String[] atNickNames = shopInfo.getNickname().split(",");
			String[] atOpenIds = shopInfo.getOpenId().split(",");

			autoCreateVideoParam.setAtUsers(atOpenIds);
			for (String atNickName : atNickNames) {
				text = text + "@" + atNickName;
			}
		}
		autoCreateVideoParam.setText(text);
		return autoCreateVideoParam;
	}

	//todo 标签删除一起删关联表 包括活动

}
